// ...existing code...
package handlers

import (
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

type BorrowRecord struct {
	ID         uint       `json:"id" gorm:"primaryKey"`
	CreatedAt  time.Time  `json:"created_at"`
	UpdatedAt  time.Time  `json:"updated_at"`
	DeletedAt  *time.Time `json:"-" gorm:"index"`
	BookID     uint       `json:"book_id" binding:"required" gorm:"index"`
	UserID     uint       `json:"user_id" binding:"required" gorm:"index"`
	BorrowedAt time.Time  `json:"borrowed_at"`
	DueAt      time.Time  `json:"due_at"`
	ReturnedAt *time.Time `json:"returned_at"`
	Fine       float64    `json:"fine" gorm:"default:0"`
	Returned   bool       `json:"returned" gorm:"default:false"`
}

func BorrowBook(db *gorm.DB) gin.HandlerFunc {
	return func(c *gin.Context) {
		var input struct {
			BookID uint `json:"book_id" binding:"required"`
			UserID uint `json:"user_id" binding:"required"`
			Days   int  `json:"days"`
		}
		if err := c.ShouldBindJSON(&input); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}

		var user User
		if err := db.First(&user, input.UserID).Error; err != nil {
			c.JSON(http.StatusNotFound, gin.H{"error": "未找到用户"})
			return
		}
		if !user.Active {
			c.JSON(http.StatusForbidden, gin.H{"error": "用户被禁用"})
			return
		}

		var cnt int64
		db.Model(&BorrowRecord{}).Where("user_id = ? AND returned = ?", user.ID, false).Count(&cnt)
		if int(cnt) >= user.BorrowLimit {
			c.JSON(http.StatusForbidden, gin.H{"error": "已达借书上限"})
			return
		}

		var book Book
		if err := db.First(&book, input.BookID).Error; err != nil {
			c.JSON(http.StatusNotFound, gin.H{"error": "未找到图书"})
			return
		}
		if !book.Available {
			c.JSON(http.StatusConflict, gin.H{"error": "图书当前不可借"})
			return
		}

		days := 14
		if input.Days > 0 {
			days = input.Days
		}
		now := time.Now()
		rec := BorrowRecord{
			BookID:     book.ID,
			UserID:     user.ID,
			BorrowedAt: now,
			DueAt:      now.AddDate(0, 0, days),
			Returned:   false,
		}
		if err := db.Create(&rec).Error; err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "创建借阅记录失败"})
			return
		}

		book.Available = false
		db.Save(&book)

		c.JSON(http.StatusCreated, rec)
	}
}

func ReturnBook(db *gorm.DB) gin.HandlerFunc {
	return func(c *gin.Context) {
		id := c.Param("id")
		var rec BorrowRecord
		if err := db.First(&rec, id).Error; err != nil {
			c.JSON(http.StatusNotFound, gin.H{"error": "未找到借阅记录"})
			return
		}
		if rec.Returned {
			c.JSON(http.StatusBadRequest, gin.H{"error": "此记录已归还"})
			return
		}

		now := time.Now()
		// 计算逾期天数（整天）
		overdue := 0
		if now.After(rec.DueAt) {
			overdue = int(now.Sub(rec.DueAt).Hours() / 24)
			if overdue < 0 {
				overdue = 0
			}
		}
		fine := float64(overdue) * 1.0

		rec.Returned = true
		rec.ReturnedAt = &now
		rec.Fine = fine
		if err := db.Save(&rec).Error; err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "保存归还信息失败"})
			return
		}

		var book Book
		if err := db.First(&book, rec.BookID).Error; err == nil {
			book.Available = true
			db.Save(&book)
		}

		c.JSON(http.StatusOK, gin.H{
			"record": rec,
			"fine":   fine,
		})
	}
}

func GetBorrowRecords(db *gorm.DB) gin.HandlerFunc {
	return func(c *gin.Context) {
		var records []BorrowRecord
		q := db.Model(&BorrowRecord{})
		if uid := c.Query("user_id"); uid != "" {
			q = q.Where("user_id = ?", uid)
		}
		if bid := c.Query("book_id"); bid != "" {
			q = q.Where("book_id = ?", bid)
		}
		if r := c.Query("returned"); r != "" {
			if r == "true" {
				q = q.Where("returned = ?", true)
			} else {
				q = q.Where("returned = ?", false)
			}
		}
		q.Find(&records)
		c.JSON(http.StatusOK, records)
	}
}
